'''
Author: yifeng
Date: 2022-08-28 19:25:41
LastEditors: yifeng
LastEditTime: 2022-10-06 21:26:01
Description: 
'''
from rest_framework import serializers
from apps.system.models import Menu, MenuButton
from apps.system.serializers.menuButtonSerializer import MenuButtonSerializer
from apps.system.serializers.customModelSerializer import CustomModelSerializer


class MenuSerializer(CustomModelSerializer):
    """
    菜单表的简单序列化器
    """
    menuPermission = serializers.SerializerMethodField(read_only=True)

    def get_menuPermission(self, instance):
        queryset = instance.menuPermission.order_by('-name').values_list('name', flat=True)
        if queryset:
            return queryset
        else:
            return None

    class Meta:
        model = Menu
        fields = "__all__"
        read_only_fields = ["id"]


class MenuCreateSerializer(CustomModelSerializer):
    """
    菜单表的创建序列化器
    """
    name = serializers.CharField(required=False)

    class Meta:
        model = Menu
        fields = "__all__"
        read_only_fields = ["id"]


class MenuInitSerializer(CustomModelSerializer):
    """
    递归深度获取数信息(用于生成初始化json文件)
    """
    name = serializers.CharField(required=False)
    children = serializers.SerializerMethodField()
    menu_button = serializers.SerializerMethodField()

    def get_children(self, obj: Menu):
        data = []
        instance = Menu.objects.filter(parent_id=obj.id)
        if instance:
            serializer = MenuInitSerializer(instance=instance, many=True)
            data = serializer.data
        return data

    def get_menu_button(self, obj: Menu):
        data = []
        instance = obj.menuPermission.order_by('method')
        if instance:
            data = list(instance.values('name', 'value', 'api', 'method'))
        return data

    def save(self, **kwargs):
        instance = super().save(**kwargs)
        children = self.initial_data.get('children')
        menu_button = self.initial_data.get('menu_button')
        # 菜单表
        if children:
            for menu_data in children:
                menu_data['parent'] = instance.id
                filter_data = {
                    "name": menu_data['name'],
                    "web_path": menu_data['web_path'],
                    "component": menu_data['component'],
                    "component_name": menu_data['component_name'],
                }
                instance_obj = Menu.objects.filter(**filter_data).first()
                if instance_obj and not self.initial_data.get('reset'):
                    continue
                serializer = MenuInitSerializer(instance_obj, data=menu_data, request=self.request)
                serializer.is_valid(raise_exception=True)
                serializer.save()
        # 菜单按钮
        if menu_button:
            for menu_button_data in menu_button:
                menu_button_data['menu'] = instance.id
                filter_data = {"menu": menu_button_data['menu'], "value": menu_button_data['value']}
                instance_obj = MenuButton.objects.filter(**filter_data).first()
                serializer = MenuButtonSerializer(instance_obj,
                                                  data=menu_button_data,
                                                  request=self.request)
                serializer.is_valid(raise_exception=True)
                serializer.save()
        return instance

    class Meta:
        model = Menu
        fields = [
            'name', 'icon', 'sort', 'is_link', 'is_catalog', 'web_path', 'component',
            'component_name', 'status', 'cache', 'visible', 'parent', 'children', 'menu_button',
            'creator', 'dept_belong_id'
        ]
        extra_kwargs = {'creator': {'write_only': True}, 'dept_belong_id': {'write_only': True}}
        read_only_fields = ['id', 'children']


class WebRouterSerializer(CustomModelSerializer):
    """
    前端菜单路由的简单序列化器
    """
    path = serializers.CharField(source="web_path")
    title = serializers.CharField(source="name")
    menuPermission = serializers.SerializerMethodField(read_only=True)

    def get_menuPermission(self, instance):
        # 判断是否是超级管理员
        if self.request.user.is_superuser:
            return instance.menuPermission.values_list('value', flat=True)
        else:
            # 根据当前角色获取权限按钮id集合
            permissionIds = self.request.user.roles.values_list('permission', flat=True)
            queryset = instance.menuPermission.filter(id__in=permissionIds,
                                                      menu=instance.id).values_list('value',
                                                                                    flat=True)
            if queryset:
                return queryset
            else:
                return None

    class Meta:
        model = Menu
        fields = ('id', 'parent', 'icon', 'sort', 'path', 'name', 'title', 'is_link', 'is_catalog',
                  'web_path', 'component', 'component_name', 'cache', 'visible', 'menuPermission')
        read_only_fields = ["id"]
